package com.esdk.utils;


import com.esdk.esdk;

import java.lang.management.ManagementFactory;

public class TestHelper{
  public static int errCount=0,successCount=0;

  public static void printAssertInfo() {
    String elapse=esdk.time.formatElapse(ManagementFactory.getRuntimeMXBean().getUptime());
    if(errCount==0)
      esdk.sout("全部测试通过，成功"+successCount+"次，耗时"+elapse);
    else
      esdk.serr("测试出错次数："+errCount+"，耗时"+elapse);
  }

  public static int getErrCount() {
    return errCount;
  }
  
  public static boolean assertEquals(boolean v) {
    return assertEquals(Boolean.valueOf(v),Boolean.TRUE);
  }
  
  public static boolean assertEquals(double actualValue,double expectValue) {
    return assertEquals(Double.valueOf(actualValue),Double.valueOf(expectValue));
  }
  public static boolean assertEquals(long actualValue,long expectValue) {
    return assertEquals(Long.valueOf(actualValue),Long.valueOf(expectValue));
  }
  public static boolean assertEquals(int actualValue,int expectValue) {
    return assertEquals(Integer.valueOf(actualValue),Integer.valueOf(expectValue));
  }
  
  public static boolean assertEquals(String actualValue,String expectValue) {
    if(actualValue==null)actualValue="";
    if(expectValue==null)expectValue="";
    return assertEquals(new TString(actualValue),new TString(expectValue));
  }
  
  public static boolean assertEqualsIgnoreCase(String actualValue,String expectValue) {
    return assertEquals(new VString(new TString(actualValue)),new VString(new TString(expectValue)));
  }
  
  public static boolean assertEquals(Object actualValue,Object expectValue){
    boolean result=false;
    try{
      if(actualValue==expectValue)
        result=true;
      else if(actualValue!=null&&expectValue!=null){
        if(actualValue.getClass()==expectValue.getClass()){
          if(expectValue instanceof TString){
            expectValue=expectValue.toString();
            actualValue=actualValue.toString();
          }
          if(expectValue instanceof String expectStr)
            expectValue=replaceWildcard(actualValue.toString(),expectStr);
          if(expectValue instanceof VString vExpectValue)
            expectValue=replaceWildcard((VString)actualValue,vExpectValue);
          if(expectValue instanceof CharSequence[] charSequences){
            expectValue=new CharAppender().append(charSequences);
            actualValue=new CharAppender().append(charSequences);
          }
          result=actualValue.equals(expectValue);
        }
        else{
          esdk.serr("ClassCastException: ActualClass:"+actualValue.getClass().getName()+"<------>"+"ExpectClass:"+expectValue.getClass().getName());
          errCount++;
//          throw new AssertException("ClassCastException: ActualClass:"+actualValue.getClass().getName()+"<------>"+"ExpectClass:"+expectValue.getClass().getName());
        }
      }
      esdk.sout("assert result: "+result);
      if(result) {
        successCount+=1;
      }
      else{
        esdk.serr("ActualValue:"+actualValue+"<------>"+"ExpectValue:"+expectValue);
        errCount++;
//        throw new AssertException("ActualValue:"+actualValue+"<------>"+"ExpectValue:"+expectValue);
      }
      return result;
    }
    catch(AssertException e){
      errCount++;
      result=false;
      return result;
    }
  }

  /**
   * 支持*号和?号的模糊匹配，以及不区分大小写
   * */
  public static boolean wildCardMatch(VString actualValue,VString expectValue) {
    return wildCardMatch(actualValue.toUpperCase(),expectValue.toUpperCase());
  }

  /**
   * 支持*号和?号的模糊匹配，区分大小写
   * */
  public static boolean wildCardMatch(String actualValue,String expectValue) {
    if(expectValue.indexOf('*')<0&&expectValue.indexOf('?')<0)
      return actualValue.compareTo(expectValue)==0;
    int start=0;
    expectValue=EasyStr.replaceAll(expectValue,"*?","*",false,true);
    StringBuffer segment=new StringBuffer();
    for(int i=0,offset=0;i<expectValue.length();i++,offset++){
      char c=expectValue.charAt(i);
      if(c!='*') {
        if(c=='?')
          c=actualValue.charAt(start+offset);    
      segment.append(c);
      }
      if((c=='*'&&segment.length()>0)||i==expectValue.length()-1) {
        int end=actualValue.indexOf(segment.toString(),start);
        if(end>=0) {
          start=end+segment.length();
        }
        else {
          return false;          
        }
        segment.delete(0,segment.length());
        offset=-1;
      }
    }
    return true;
  }
  
  public static VString replaceWildcard(VString actualValue,VString expectValue) {
    if(wildCardMatch(actualValue,expectValue))
      return actualValue;
    else
      return expectValue;
  }

  public static String replaceWildcard(String actualValue,String expectValue) {
    if(wildCardMatch(actualValue,expectValue))
      return actualValue;
    else
      return expectValue;
  }

  public static void main(String[] args){
    assertEquals(wildCardMatch("abcd","a?cd"));
    assertEquals(wildCardMatch("!can not sign because task[id=14] has not completed.","!can not sign because task[id=??] has not completed."));
    assertEquals(wildCardMatch("aabbccdd","*a*bb*cd*d*"));
    assertEquals(!wildCardMatch("aabbccdd","a*a*bb*cd*d*d"));
    assertEquals(wildCardMatch("aabbccddee","a*a*b?*?d*d??"));
    assertEquals(!replaceWildcard("1234567890","*1*0*0").equals("1234567890"));
    assertEquals(replaceWildcard("12344","1*44").equals("12344"));
    assertEquals(replaceWildcard("12344","1*4").equals("12344"));
    assertEquals(replaceWildcard("1234567890","1*0").equals("1234567890"));
    assertEquals(replaceWildcard("1234567890","1*7*9*").equals("1234567890"));
    assertEquals(replaceWildcard("1234567890","*1*0**").equals("1234567890"));
    assertEquals(replaceWildcard("1234567890","*1*0").equals("1234567890"));
    assertEquals(replaceWildcard("1234567890","1*0").equals("1234567890"));
    assertEquals(replaceWildcard("1234567890","1*").equals("1234567890"));
    assertEquals(replaceWildcard("1234567890","*").equals("1234567890"));
   printAssertInfo();
  }
}
